import requests
from typing import Dict, Any, Optional
from pathlib import Path
from .logger import test_logger

class BaseTest:
    """测试框架的基础类"""
    
    def __init__(self, base_url: str):
        self.base_url = base_url
        self.session = requests.Session()
        self.session.base_url = base_url
        self.logger = test_logger.get_logger(self.__class__.__name__)
        
    def setup(self):
        """测试前的准备工作"""
        pass
        
    def teardown(self):
        """测试后的清理工作"""
        self.session.close()
        
    def execute_request(self, method: str, endpoint: str, 
                       headers: Optional[Dict[str, str]] = None,
                       json: Optional[Dict[str, Any]] = None) -> requests.Response:
        """执行HTTP请求"""
        self.logger.info(f"Executing {method.upper()} request to {endpoint}")
        return getattr(self.session, method.lower())(endpoint, headers=headers, json=json)
        
    def validate_response(self, response: requests.Response, 
                         expected_status: int,
                         expected_data: Optional[Dict[str, Any]] = None):
        """验证响应数据"""
        assert response.status_code == expected_status, \
            f"Expected status {expected_status}, but got {response.status_code}"
            
        if expected_data:
            self._validate_data(response.json(), expected_data)
            
    def _validate_data(self, actual: Dict[str, Any], expected: Dict[str, Any]):
        """递归验证响应数据"""
        for key, value in expected.items():
            assert key in actual, f"Expected key '{key}' not found in response"
            
            if isinstance(value, dict):
                self._validate_data(actual[key], value)
            elif isinstance(value, list):
                assert len(actual[key]) == len(value), \
                    f"Expected {len(value)} items, but got {len(actual[key])}"
                for actual_item, expected_item in zip(actual[key], value):
                    self._validate_data(actual_item, expected_item)
            elif value == "string":
                assert isinstance(actual[key], str), \
                    f"Expected string, but got {type(actual[key])}"
            else:
                assert actual[key] == value, \
                    f"Expected {value}, but got {actual[key]}" 